#ifndef _OS_H_H_

#define _OS_H_H_

#ifndef SIP_CLIENT
#ifndef WIN32
#define _LINUX_ 1
#endif
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "base.h"

#ifdef WIN32
#pragma warning(disable:4786)
#pragma warning(disable:4503)
#pragma warning(disable:4530)
#define WIN32_LEAN_AND_MEAN
#ifdef IPV6_SUPPORTED
#include <winsock2.h>
#include <ws2tcpip.h>

#else

#include <winsock2.h>
#endif
#include <time.h>
#include <direct.h>

#else

#include <ctype.h>
#include <sys/types.h> 
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/times.h>
#include <netinet/in.h>
#include <netinet/tcp.h>	// added by StoneWhoo for TCP_NODELAY option macro!
#include <arpa/inet.h>
#include <netdb.h>
#include <signal.h>
#include <pthread.h>
#include <pwd.h>
#include <unistd.h>
#include <limits.h>
#include <semaphore.h>
#include <strings.h>
//#include <stropts.h>
#include <syslog.h>
#include <fcntl.h>
#include <sys/time.h>
#include <errno.h>

#ifdef _LINUX_
#include <sys/wait.h>
#else
#include <sys/filio.h>
#endif

#endif

////////////added by cloud.qin///////////////////////////
#define  UINT          unsigned int
#define  BYTE          unsigned char
#define  WORD          unsigned short
#define  DWORD         unsigned long
#define  DWORD_PTR     DWORD
#define  LONG          long
#ifndef MAKEWORD   
#define  MAKEWORD(a, b)      ((WORD)(((BYTE)((DWORD_PTR)(a) & 0xff)) | ((WORD)((BYTE)((DWORD_PTR)(b) & 0xff))) << 8))
#define  MAKELONG(a, b)      ((LONG)(((WORD)((DWORD_PTR)(a) & 0xffff)) | ((DWORD)((WORD)((DWORD_PTR)(b) & 0xffff))) << 16))

#define  LOWORD(l)           ((WORD)((DWORD_PTR)(l) & 0xffff))
#define  HIWORD(l)           ((WORD)((DWORD_PTR)(l) >> 16))
#define  LOBYTE(w)           ((BYTE)((DWORD_PTR)(w) & 0xff))
#define  HIBYTE(w)           ((BYTE)((DWORD_PTR)(w) >> 8))
#endif
//end //////
/////////////////////////////////////////////////////////////

// Added by Stone Whoo for int64 types 
#ifdef _LINUX_
typedef long long int int64;
typedef unsigned long long int uint64;

#define STRINGTO64LONG(x)  atoll(x)

#define	PathDelimiterChar '/'

#define WSADESCRIPTION_LEN      256
#define WSASYS_STATUS_LEN       128

typedef struct WSAData {
        WORD                    wVersion;
        WORD                    wHighVersion;
        char                    szDescription[WSADESCRIPTION_LEN+1];
        char                    szSystemStatus[WSASYS_STATUS_LEN+1];
        unsigned short          iMaxSockets;
        unsigned short          iMaxUdpDg;
        char *              lpVendorInfo;
} WSADATA, *LPWSADATA;

#elif defined(WIN32)

#define	PathDelimiterChar '\\'

typedef __int64		int64;
typedef unsigned __int64		uint64;

#define  STRINGTO64LONG(x)  _atoi64(x)

#endif
// end add

typedef int	int32;
typedef short	int16;
typedef char	int8;
typedef unsigned long	uint32;
typedef unsigned short	uint16;
typedef unsigned char	uint8;
typedef unsigned int	uint;
#ifndef WIN32
#define HANDLE	pthread_t
#define SOCKET  int
#define INVALID_SOCKET	-1
#define SOCKET_ERROR	-1
#define closesocket close
#define stricmp  strcasecmp
typedef const char* LPCTSTR;
typedef  off64_t  int64;

#else
#define pthread_t HANDLE
#define pthread_mutex_t HANDLE
#define pthread_attr_t	SECURITY_ATTRIBUTES
#define sem_t	HANDLE
typedef int socklen_t;
typedef __int64		int64;
typedef fpos_t	fpos64_t;
#define useconds_t uint32
#define 	fopen64 fopen
#define     fseeko64 fseek
#define     fgetpos64 fgetpos
#define     ftello64	ftell
//#define EBADF	WSAENOTSOCK
#endif
#ifndef BOOL	
#define BOOL	int
#endif
#ifndef TRUE
#define TRUE	1
#endif
#ifndef FALSE
#define FALSE	0
#endif
#ifndef MAX_PATH
#define MAX_PATH 256
#endif
#ifndef NULL
#define NULL 0
#endif

// common functions
#ifdef WIN32
#define MKDIR(dir, mod)	mkdir(dir)	
#else
#define MKDIR(dir, mod)	mkdir(dir, mod)
#endif

#ifdef _LINUX_
long GetTickCount();
int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
int  WSACleanup (void);

BOOL SetThreadPriority(
						  HANDLE hThread, // handle to the thread
						  int nPriority   // thread priority level
						);

/*
int strcmp(const char *s1, const char *s2);
*/
//int strcasecmp(const char *s1, const char *s2);
int stricmp(const char *s1, const char *s2)throw();
//int strncasecmp(const char *s1, const char *s2, size_t n);
int strnicmp(const char *s1, const char *s2, size_t n)throw();
char* itoa(int value, char*  str, int radix);
char* strrev(char* szT);
#endif

// set/reset the non-blocking io mode
bool NonblockMode(SOCKET s, bool bnonblock, int rcvbufsize, int sndbufsize, bool btcp=false);
// set/reset the socket reusable mode
bool SetAddrReusable(SOCKET s, bool busable);

// set time out!
// ntime unit is second
bool SetRecvTimeout(SOCKET s, int ntime);
bool SetSendTimeout(SOCKET s, int ntime);
// ntime returns actual value
bool GetRecvTimeout(SOCKET s, int& ntime);
bool GetSendTimeout(SOCKET s, int& ntime);

#ifdef WIN32
struct timeval;
int BASE_API pthread_create(pthread_t *thread,  const  pthread_attr_t *attr, void *(*start_routine)(void*),void *arg);
int BASE_API pthread_join(pthread_t thread, void **value_ptr);
void BASE_API pthread_exit(void *value_ptr);
int BASE_API usleep(useconds_t useconds);
int BASE_API gettimeofday(timeval *tp,void *);
int BASE_API pthread_detach(pthread_t thread);
pthread_t BASE_API pthread_self(void);

void BASE_API bzero(void *s, int n);

#define  pthread_mutex_init(A, B)   InitializeCriticalSection(A) 
#define  pthread_mutex_lock(A)   (EnterCriticalSection(A),0) 
#define  pthread_mutex_unlock(A)   LeaveCriticalSection(A) 
#define  pthread_mutex_destroy(A)   DeleteCriticalSection(A) 
#define  pthread_handler_decl(A, B)   unsigned __cdecl A(void *B) 


#else
#include <pthread.h>
#endif
#endif

